const gulp = require('gulp');
const jade = require('gulp-jade');
const stylus = require('gulp-stylus');
const plumber = require('gulp-plumber');
const autoprefixer = require('gulp-autoprefixer');
const babel = require('rollup-plugin-babel');
const resolve = require('rollup-plugin-node-resolve')
const commonjs = require('rollup-plugin-commonjs');
const replace = require('rollup-plugin-replace');
const uglify = require('rollup-plugin-uglify');
const progress = require('rollup-plugin-progress');
const rollup = require('rollup');
const browserSync = require('browser-sync').create();

const option = (env) => {
  return {
    entry: './src/main.js',
    plugins: [
      babel({
        exclude: 'node_modules/**',
        runtimeHelpers: true
      }),
      commonjs(),
      resolve({
        jsnext: true,
        browser: !env
      }),
      progress({
        clearLine: false
      }),
      replace({
        ENV: JSON.stringify(env || 'development')
      }),
      (env === 'production' && uglify())
    ]
  }
};

let cache = {};
let format = 'iife';
let dest = './dist/main.js';

const bundleWrite = (bundle) => {
  console.log('[RD]', 'Writing bundle...')
  cache = bundle;
  bundle.write({
    format,
    dest,
    sourceMap: 'inline'
  })
};

const rollupfn = (env) => {
  console.log('[RO] INGING ...');
  return rollup.rollup(option(env))
    .then(function (bundle) {
      bundle.write({
        format,
        dest,
        sourceMap: false
      });
    })
};

gulp.task('jade', () => {
  return gulp.src('./src/*.jade')
    .pipe(plumber({
      errorHandler(err) {
        this.emit('end')
      }
    }))
    .pipe(jade({
      pretty: true
    }))
    .pipe(gulp.dest('./dist'));
});

gulp.task('styl', () => {
  return gulp.src('./src/*.styl')
    .pipe(plumber({
      errorHandler(err) {
        this.emit('end')
      }
    }))
    .pipe(stylus({
      compress: true
    }))
    .pipe(autoprefixer({
      browsers: ['last 5 versions', 'Android >= 4.0']
    }))
    .pipe(gulp.dest('./dist'));
});


// build
gulp.task('build', ['jade', 'styl'], () => {
  return rollupfn('production');
});

// dev
gulp.task('dev', ['jade', 'styl'], () => {
  browserSync.init({
    server: "./dist"
  });
  let opd = option();
  rollup.rollup(opd)
    .then(bundleWrite)
    .then(() => {
      gulp.watch('./src/*.js').on('change', () => {
        rollup.rollup(Object.assign({}, opd, {
            cache
          }))
          .then(bundleWrite)
      });
    });
  gulp.watch('./src/*.jade', ['jade']);
  gulp.watch('./src/*.styl', ['styl']);
  gulp.watch('./dist/**').on('change', browserSync.reload);
});
